package com.sinosoft.hydra.um.services;

import cn.com.sinux.spring.utils.DateUtils;
import cn.com.sinux.spring.utils.SpecificationHelper;
import com.sinosoft.hydra.um.condition.SearchAttendanceCondition;
import com.sinosoft.hydra.um.domain.permission.TAttendance;
import com.sinosoft.hydra.um.domain.permission.TMeeting;
import com.sinosoft.hydra.um.helper.AuthContextHelper;
import com.sinosoft.hydra.um.repositories.TMeetingDAO;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;
import java.util.List;

@Service
public class MeetingService {
    @Autowired
    private TMeetingDAO meetingDAO;

    public boolean isMeetingConflictWithExisting(TMeeting meeting) {
        final Date date = meeting.getDate();
        Specification<TMeeting> specification = SpecificationHelper.buildSpecification(new SpecificationHelper.SpecificationBuilder<TMeeting>() {
            public void fillParam(Root<TMeeting> root, CriteriaBuilder cb, List<Predicate> list) {
                list.add(cb.and(
                        cb.lessThanOrEqualTo(root.get("date").as(Date.class), DateUtils.getEndOfDay(date)),
                        cb.greaterThanOrEqualTo(root.get("date").as(Date.class), DateUtils.getStartOfDay(date))
                ));
            }
        });
        List<TMeeting> meetingsOfDate = meetingDAO.findAll(specification);
        int start = meeting.getBeginTimeIndex();
        int end = start + meeting.getSlotCount();
        boolean isConflict = false;
        for(TMeeting m : meetingsOfDate) {
            if (end > m.getBeginTimeIndex() && start < m.getBeginTimeIndex() + m.getSlotCount()) {
                isConflict = true;
                break;
            }
        }

        return isConflict;
    }

    public TMeeting addMeeting(TMeeting meeting) {
        meeting.setReserveUser(AuthContextHelper.getLoginUser());
        return meetingDAO.save(meeting);
    }

    public TMeeting deleteMeeting(String id) {
        TMeeting meeting = StringUtils.isBlank(id)? null : meetingDAO.findOne(id);
        if (meeting == null) {
            return null;
        }

        meetingDAO.delete(id);
        return meeting;
    }

    public Page<TMeeting> findReservationsForDate(final Date date, Pageable pageable) {
        Specification<TMeeting> specification = SpecificationHelper.buildSpecification(new SpecificationHelper.SpecificationBuilder<TMeeting>() {
            public void fillParam(Root<TMeeting> root, CriteriaBuilder cb, List<Predicate> list) {
                list.add(cb.and(
                        cb.lessThanOrEqualTo(root.get("date").as(Date.class), DateUtils.getEndOfDay(date)),
                        cb.greaterThanOrEqualTo(root.get("date").as(Date.class), DateUtils.getStartOfDay(date))
                ));
            }
        });
        return meetingDAO.findAll(specification, pageable);
    }
}
